package net.jjjshop.common.factory.paysuccess.type.impl;

import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import net.jjjshop.common.entity.order.Order;
import net.jjjshop.common.entity.order.OrderCreditPay;
import net.jjjshop.common.entity.order.OrderProduct;
import net.jjjshop.common.entity.user.User;
import net.jjjshop.common.entity.user.UserBalanceLog;
import net.jjjshop.common.enums.*;
import net.jjjshop.common.factory.paysuccess.source.PaySuccessSourceFactory;
import net.jjjshop.common.factory.paysuccess.type.PaySuccessOrder;
import net.jjjshop.common.factory.paysuccess.type.PaySuccessTypeFactoryService;
import net.jjjshop.common.factory.product.ProductFactory;
import net.jjjshop.common.mapper.order.OrderMapper;
import net.jjjshop.common.service.order.OrderCreditPayService;
import net.jjjshop.common.service.order.OrderProductService;
import net.jjjshop.common.service.order.OrderService;
import net.jjjshop.common.service.user.UserBalanceLogService;
import net.jjjshop.common.service.user.UserService;
import net.jjjshop.common.util.OrderUtils;
import net.jjjshop.common.util.alimini.AlipayUtils;
import net.jjjshop.common.vo.order.PayDataVo;
import net.jjjshop.framework.common.api.ApiResult;
import net.jjjshop.framework.common.exception.BusinessException;
import net.jjjshop.framework.util.DateUtil;
import net.jjjshop.framework.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * 支付成功
 */
@Slf4j
@Service
public class MasterPaySuccessTypeFactoryService extends PaySuccessTypeFactoryService {
    @Autowired
    private OrderService orderService;
    @Autowired
    private UserService userService;
    @Autowired
    private ProductFactory productFactory;
    @Autowired
    private OrderProductService orderProductService;
    @Autowired
    private UserBalanceLogService userBalanceLogService;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private PaySuccessSourceFactory paySuccessSourceFactory;
    @Autowired
    private OrderCreditPayService orderCreditPayService;
    @Autowired
    private AlipayUtils alipayUtils;
    /**
     * 支付成功处理
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean onPaySuccess(String out_order_no, Integer payStatus, Integer payType, PayDataVo payData){
        Order order = this.getPayDetail(out_order_no, payStatus);
        if (order == null) {
            log.info("未找到该订单信息, tradeNo={}", out_order_no);
            return false;
        }
        // 更新订单状态
        this.updateOrderInfo(order, payType, payData);
        // 累积用户总消费金额
        this.setIncPayMoney(order.getUserId(), order.getPayPrice());
        // 记录订单支付信息
        this.updatePayInfo(order);
        // 订单支付成功行为,异步执行
        paySuccessSourceFactory.getFactory(order.getOrderSource()).onPaySuccess(order.getOrderId());
        return true;
    }

  /**
     * 芝麻先享扣款成功处理
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean onAuthPaySuccess(String out_order_no, Integer payStatus, Integer payType, HashMap<String, String> params) throws AlipayApiException {
        Order order = this.getPayDetail(out_order_no, payStatus);
        if (order == null) {
            //有可能是芝麻免押扣款
            OrderCreditPay orderC = orderCreditPayService.getOne(new LambdaQueryWrapper<OrderCreditPay>()
                    .eq(OrderCreditPay::getOutTradeNo, out_order_no));
            if (orderC != null) {
                 order = orderService.getById(orderC.getOrderId());
            }
            if (order == null) {
                log.info("未找到该订单信息, out_order_no={}", out_order_no);
                return false;
            }
        }
        if (order.getOrderStatus().equals(OrderStatusEnum.COMPLETED.getValue())) {
            log.info("订单已完成,无需修改, out_order_no={}", out_order_no);
            return false;
        }
        //更新订单状态
        order.setAuthRemark( DateUtil.getDateString(new Date()) + "系统扣款,金额:"+params.get("receipt_amount")+"元成功;<br/>"+order.getAuthRemark() );
        //记录订单
        OrderCreditPay orderCreditPay = orderCreditPayService.getOne(new LambdaQueryWrapper<OrderCreditPay>().eq(OrderCreditPay::getOrderId, order.getOrderId()).last("order by order_credit_pay_id desc limit 1"));
        BigDecimal shengyudaikou = order.getPayPrice().subtract(order.getDeductionMoney());
        if (order.getZmDeductStatus()==20||shengyudaikou.compareTo(orderCreditPay.getPayPrice()) == 0) {
            order.setZmDeductStatus(20);
        }

        order.setDeductionMoney(order.getDeductionMoney().add(orderCreditPay.getPayPrice()));


        orderCreditPay.setPayStatus(20);
        orderCreditPay.setPayTime(new Date());
//        orderCreditPay.setPayPrice(new BigDecimal(params.get("receipt_amount")));
        orderCreditPayService.updateById(orderCreditPay);
        if (order.getPayPrice().compareTo(order.getDeductionMoney()) == 0) {
            order.setOrderStatus(OrderStatusEnum.COMPLETED.getValue());
            if (order.getPayType().equals(OrderPayTypeEnum.ALIPAY_MY.getValue())) {
                alipayUtils.zmmyUnfreeze(OrderUtils.geneOrderNo(order.getUserId()),order.getCreditBizOrderId(),order.getPayPrice());
            }else if(order.getPayType().equals(OrderPayTypeEnum.ALIPAY_XX.getValue())){
                alipayUtils.finishOrder(params.get("credit_biz_order_id"),params.get("out_order_no"));
            }
        }
        orderService.updateById(order);
        return true;
    }

    /**
     * 支付成功订单信息
     */
    public PaySuccessOrder getOrder(String outOrderNo){
        Order order = this.getPayDetail(outOrderNo, 0);
        PaySuccessOrder paySuccessOrder = new PaySuccessOrder();
        paySuccessOrder.setPayStatus(order.getPayStatus());
        paySuccessOrder.setAppId(order.getAppId());
        return paySuccessOrder;
    }

    /**
     * 获取订单
     * @return
     */
    private Order getPayDetail(String OutOrderNo, Integer payStatus){
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getOutOrderNo, OutOrderNo);
        if(payStatus > 0){
            wrapper.eq(Order::getPayStatus, payStatus);
        }
        return orderService.getOne(wrapper);
    }

    /**
     * 更新订单记录
     */
    private void updateOrderInfo(Order order, Integer payType, PayDataVo payData)
    {
        // 更新商品库存、销量
        productFactory.getFactory(order.getOrderSource()).updateProductStockSales(orderUtils.getOrderProduct(order.getOrderId()));
        // 整理订单信息
        String paySource = "";
        if (payData.getAttach() != null) {
            paySource = payData.getAttach().getString("paySource");
        }
        Order updateOrder = new Order();
        updateOrder.setOrderId(order.getOrderId());
        updateOrder.setPayType(payType);
        updateOrder.setPayStatus(20);
        updateOrder.setPayTime(new Date());
        updateOrder.setPaySource(paySource);
        updateOrder.setTransactionId(payData.getTransaction_id());
        if (payType == OrderPayTypeEnum.ALIPAY_XX.getValue()||payType == OrderPayTypeEnum.ALIPAY_MY.getValue()) {
            updateOrder.setAuthAuditStatus(OrderPayAuthStatusEnum.NORMAL.getValue());
            updateOrder.setAuthStatus(OrderAuthStatusEnum.PASS_THE_AUDIT.getValue());
            updateOrder.setCreditBizOrderId(payData.getCredit_biz_order_id());
        }
        // 更新订单状态
        orderService.updateById(updateOrder);
    }

    /**
     * 累计用户消费金额
     * @param userId
     * @param payPrice
     */
    private void setIncPayMoney(Integer userId, BigDecimal payPrice){
        userService.update(new LambdaUpdateWrapper<User>().eq(User::getUserId, userId)
                .setSql("`pay_money` = `pay_money` + " + payPrice));
    }

    /**
     * 记录支付信息
     */
    private void updatePayInfo(Order order){
        // 余额支付
        if(order.getBalance().compareTo(BigDecimal.ZERO) > 0){
            // 更新用户余额
            userService.update(new LambdaUpdateWrapper<User>().eq(User::getUserId, order.getUserId())
                    .setSql("`balance` = `balance` - " + order.getBalance()));
            // 记录日志
            UserBalanceLog log = new UserBalanceLog();
            log.setUserId(order.getUserId());
            log.setMoney(order.getBalance().negate());
            log.setScene(BalanceLogEnum.CONSUME.getValue());
            log.setDescription(String.format("用户消费：%s", order.getOrderNo()));
            userBalanceLogService.save(log);
        }
    }



}
